import * as THREE from "three";
import {
    Selector
} from "@/components/commonCom/Three/Selector.js";
import {
    setupEventListeners
} from "@/components/commonCom/Three/Mouse.js";

import * as dat from 'dat.gui';
import {
    log
} from "three/tsl";
export function Viewport(dom, {
    modelSrc
}) {
    let stats, clock, gui, mixer, actions, previousAction;
    let camera, scene, renderer, model, orbit;
    let width, height, rectRight, rectLeft;
    const v2_down = new THREE.Vector2();
    const v2_up = new THREE.Vector2();
    const v2 = new THREE.Vector2();
    let activeObject
    let select = null;
    let activeName, defaultName = 'Idle',
        animationsName = [];

    function GuiInit() {
        const gui = new dat.GUI();
        // box控制
        const folderBox = gui.addFolder("立方体控制");
        folderBox.add(camera.position, "x", -2, 2).step(0.01);
        folderBox.add(camera.position, "y", 0, 2);
        folderBox.add(camera.position, "z", 0, 4);
        const folderBox2 = gui.addFolder("旋转");
        folderBox2.add(camera.rotation, "x", -2, 2).step(0.01);
        folderBox2.add(camera.rotation, "y", -2, 2).step(0.01);
        folderBox2.add(camera.rotation, "z", -2, 4).step(0.01);
        // folderBox.addColor(params.boxParam, "color").onChange(function (value) {
        //     material.color.set(value);
        // });
        folderBox.open()
        folderBox2.open()

    }
    // 监听点击事件
    this.init = function (callback) {
        const rect = dom.getBoundingClientRect();
        width = rect.width;
        height = rect.height;
        rectLeft = rect.left;
        rectRight = rect.right;

        camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 10000);
        camera.position.set(-0.05, 1.2, 3.5)
        camera.rotation.set(0, 0.06, 0);

        scene = new THREE.Scene();
        // scene.background = new THREE.Color(0xffffff);
        scene.background = null;

        clock = new THREE.Clock();

        // lights

        // const hemiLight = new THREE.HemisphereLight(0xffffff, 0x8d8d8d, 3);
        // hemiLight.position.set(0, 20, 0);
        // scene.add(hemiLight);
        const ambientLight = new THREE.AmbientLight(0xffffff, 2);
        scene.add(ambientLight);
        const dirLight = new THREE.DirectionalLight(0xffffff, 1.5);
        dirLight.position.set(0, 20, 10);
        scene.add(dirLight);

        // ground
        const mesh = new THREE.Mesh(
            new THREE.PlaneGeometry(2000, 2000),
            new THREE.MeshPhongMaterial({
                color: 0xcbcbcb,
                depthWrite: false
            })
        );
        mesh.rotation.x = -Math.PI / 2;
        // scene.add(mesh);

        const grid = new THREE.GridHelper(200, 40, 0x000000, 0x000000);
        grid.material.opacity = 0.2;
        grid.material.transparent = true;
        // scene.add(grid);
        select = new Selector(scene)
        // model
        async function loadModel() {

            const loader = await createGLTFLoader();

            const glb = await new Promise((resolve, reject) => {
                loader.load(modelSrc, resolve, undefined, reject);
            });

            let model = glb.scene;
            animationsName = glb.animations.map(ele => ele.name);

            model.traverse(function (child) {
                if (child.isMesh && child.material.name == 'beijing') {
                    // 
                    let material = new THREE.MeshBasicMaterial({
                        map: child.material.map
                        // wireframe: true,
                    });
                    child.material = material;

                }
            });

            setAniamtion(model, glb.animations);

            callback()
            scene.add(model);
        }
        loadModel();

        async function createGLTFLoader() {
            const {
                GLTFLoader
            } = await import("three/addons/loaders/GLTFLoader.js");
            const {
                DRACOLoader
            } = await import("three/addons/loaders/DRACOLoader.js");
            const dracoLoader = new DRACOLoader();
            dracoLoader.setDecoderPath("/draco/");
            const loader = new GLTFLoader();
            loader.setDRACOLoader(dracoLoader);

            return loader;
        }
        renderer = new THREE.WebGLRenderer({
            antialias: true,
            alpha: true
        });
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(width, height);
        renderer.setAnimationLoop(animate);

        dom.appendChild(renderer.domElement);
        // GuiInit();
        window.addEventListener("resize", onWindowResize);
    }

    function setAniamtion(model, animations) {

        mixer = new THREE.AnimationMixer(model);

        actions = {};

        for (let i = 0; i < animations.length; i++) {
            const clip = animations[i];
            const action = mixer.clipAction(clip);
            actions[clip.name] = action;
        }

        // 默认播放走路动画
        if (actions[defaultName]) {
            actions[defaultName].play();
        }
    }
    this.useAnimation = function (name, LoopRepeat = Infinity, callback) {
        activeName = name;
        if (actions[activeName]) {
            animationsName.forEach(name => {

                const action = actions[name];
                action.stop();
                action.reset();
                action.paused = false;
                action.enabled = true;

                if (activeName === name) {

                    action.setLoop(THREE.LoopRepeat, LoopRepeat);
                    action.play();

                    if (this._finishedListener) {
                        mixer.removeEventListener('finished', this._finishedListener);
                    }

                    action.clampWhenFinished = true;

                    this._finishedListener = function (e) {
                        if (callback) {
                            callback();
                        }
                    };
                    mixer.addEventListener('finished', this._finishedListener);
                }
            });
        }


    }

    this.animtionReset = () => {
        // 播放走路动画
        if (actions[activeName]) {
            actions[activeName].stop();
        }
    }


    function animtionReset() {
        previousAction = null;
        // 播放走路动画
        if (actions[defaultName]) {
            actions[defaultName].play();
            if (actions[activeName]) {
                actions[activeName].stop();

            }
        }
    }


    function onWindowResize() {
        camera.aspect = width / height;
        camera.updateProjectionMatrix();

        renderer.setSize(width, height);
    }

    //

    function animate() {
        const dt = clock.getDelta();

        if (mixer) mixer.update(dt);
        renderer.render(scene, camera);
    }

    this.mouseEventHandler = (eventType, callback) => {

        setupEventListeners(dom, eventType, select, camera, (intersects) => {

            if (intersects.length > 0) {
                const intersect = intersects[0];
                callback(intersect, eventType);

            } else {
                callback(intersects, eventType); 
            }

        });




    }
}